////
//// Created by quzheng on 2023/4/28.
////
//
//#include <iostream>
//#include <typeinfo>
////#include <boost/type_index.hpp>
////using boost::typeindex::type_id_with_cvr;
//
//class BaseExp{
//public:
//    virtual int eval(int i) const = 0;
//};
//
//template<typename TLHs, typename TRHs>
//class AddExp:public BaseExp{
//private:
//    const TLHs &_lhs;
//    const TRHs &_rhs;
//public:
//    AddExp(const TLHs &lhs, const TRHs &rhs):_lhs(lhs), _rhs(rhs){};
//    int eval(int i) const{
//        return _lhs.eval(i) + _rhs.eval(i);
//    };
//};
//template<typename TLHs, typename TRHs>
//AddExp<TLHs, TRHs> operator+(const TLHs& lhs, const TRHs& rhs){
////    std::cout << "temtype=" << type_id_with_cvr<TLHs>().pretty_name() << std::endl;//显示T类型
//    return AddExp<TLHs, TRHs>(lhs, rhs);
//}
//
//class Vec :public BaseExp{
//public:
//    int _len;
//    int* _ptr;
//    void show(){
//        for(int i = 0; i < _len; i++){
//            std::cout<<_ptr[i]<<",  ";
//        }
//        std::cout<<"\n";
//    };
//    Vec(void){};
//    Vec(int n, int* inPtr) : _len(n), _ptr(inPtr){};
//    template<typename T>
//    Vec& operator=(T src){
//        for(int i = 0; i < _len; i++){
//            _ptr[i] = src.eval(i);
//        }
//        return *this;
//    }
//    int eval(int i) const{
//        return _ptr[i];
//    }
//};
//
//int main()
//{
//    int a[] = {1,2,3};
//    int b[] = {4,5,6};
//    int c[] = {7,8,9};
//    Vec va(3, a), vb(3, b), vc(3, c);
//    Vec resv(3, a);
//
//    va.show();
//    vb.show();
//    vc.show();
//
//    resv = va + vb + vc + vc;
//    // std::cout <<typeid( va + vb + vc).name() << std::endl;
//    // resv = va + vb + vc;
//    resv.show();
//    return 0;
//}


#include <iostream>
//#include <boost/type_index.hpp>
//using boost::typeindex::type_id_with_cvr;
template<typename T>
class BaseExp{
public:
    inline const T& cast(void) const{
        return *static_cast<const T*>(this);
    };
};

template<typename TLHs, typename TRHs>
class AddExp:public BaseExp<AddExp<TLHs, TRHs> >{
private:
    const TLHs &_lhs;
    const TRHs &_rhs;
public:
    AddExp(const TLHs &lhs, const TRHs &rhs):_lhs(lhs), _rhs(rhs){};
    int eval(int i) const{
        return _lhs.eval(i) + _rhs.eval(i);
    };
};
template<typename TLHs, typename TRHs>
AddExp<TLHs, TRHs> operator+(const BaseExp<TLHs>& lhs, const BaseExp<TRHs>& rhs){
//    std::cout << "temtype=" << type_id_with_cvr<TLHs>().pretty_name() << std::endl;//显示T类型
    return AddExp<TLHs, TRHs>(lhs.cast(), rhs.cast());
}
class Vec :public BaseExp<Vec>{
public:
    int _len;
    int* _ptr;
    void show(){
        for(int i = 0; i < _len; i++){
            std::cout<<_ptr[i]<<",  ";
        }
        std::cout<<"\n";
    };
    Vec(void){};
    Vec(int n, int* inPtr) : _len(n), _ptr(inPtr){};
    template<typename T>
    Vec& operator=(const BaseExp<T>& src){
        const T &tmpSrc = src.cast();
        for(int i = 0; i < _len; i++){
            _ptr[i] = tmpSrc.eval(i);
        }
        return *this;
    }
    int eval(int i) const{
        return _ptr[i];
    }
};

int main()
{
    int a[] = {1,2,3};
    int b[] = {4,5,6};
    int c[] = {7,8,9};
    Vec va(3, a), vb(3, b), vc(3, c);
    Vec resv(3, a);

    va.show();
    vb.show();
    vc.show();
    // std::cout<<"va ptr: "<<va._ptr<<":"<<va._ptr[0]<<".\n";
    // std::cout<<"vb ptr: "<<vb._ptr<<":"<<vb._ptr[0]<<".\n";
    // resv = va + vb + vc;   //record
    va + vb;

    resv = va + vb + vc + vc;
    resv.show();
    return 0;
}